package pers.cj.pdos.utils;

import pers.cj.pdos.entity.Company;
import pers.cj.pdos.entity.InGoods;
import pers.cj.pdos.exception.CustomException;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * 数据操作。主要是初始化id,time,companyId
 */
public class DataUtil {

    /**
     * 从list结构体提取出map，
     * @param keyName - E的属性名
     * @param list - 列表
     * @param <E> - 类型
     * @return
     */
    public static <E> Map<String,E> genMap(String keyName, List<E> list){
        Map<String,E> map = new HashMap<>();
        if (Utils.isEmpty(list)) {
            return map;
        }

        for (E e : list) {
            //从数据e获取的值作为key
            String key = (String) ReflectionUtils.getFieldValue(e,keyName);
            if (!Utils.isEmpty(key)) {
                map.put(key, e);
            }
        }
        return map;
    }


    /**
     * 根据entity对象创建其子类vo的对象
     * @param voClass
     * @param entity
     * @param <E>
     * @return
     */
    public static <E> E genVoFromEntity(Class voClass, Object entity){
        try {
            //创建返回的对象
            E vo = (E)voClass.getConstructor().newInstance();
            for (Field field : entity.getClass().getDeclaredFields()) {
                if(Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) {
                    continue;
                }

                String fieldName = field.getName();
                Object value = ReflectionUtils.getFieldValue(entity,fieldName);
                ReflectionUtils.setFieldValue(vo, fieldName, value);
            }
            return vo;
        } catch (Exception e) {
            throw new CustomException("vo对象的类型不是entityClass的子类");
        }
    }

    /**
     * 根据vo创建其父类并返回出去
     * @param entityClass
     * @param vo
     * @param <E>
     * @return
     */
    public static <E> E genEntityFromVo(Class entityClass, Object vo) {
        try {
            //创建返回的对象
            E entity = (E)entityClass.getConstructor().newInstance();
            for (Field field : entityClass.getDeclaredFields()) {
                if(Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) {
                    continue;
                }

                String fieldName = field.getName();
                Object value = ReflectionUtils.getFieldValue(vo,fieldName);
                ReflectionUtils.setFieldValue(entity, fieldName, value);
            }
            return entity;
        } catch (Exception e) {
            throw new CustomException("vo对象的类型不是entityClass的子类");
        }
    }


    public static synchronized List<String> genIds(List list){
        List<String> ids = new ArrayList<>();
        if (Utils.isEmpty(list)){
            return ids;
        }
        try {
            for (Object object : list){
                ids.add((String) ReflectionUtils.getFieldValue(object,"id"));
            }
            return ids;
        } catch (Exception e) {
            return ids;
        }
    }






    public static void processEntity(Company company, Object data) {
        processEntity(true,company, data, null);
    }
    public static void processEntity(boolean initId,Company company, Object data) {
        processEntity(initId,company, data, null);
    }
    public static void processEntity(Company company,Object data, Map<String, Object> map) {
        processEntity(true,company, data, map);
    }

    public static void processList(Company company, List list) {
        if (Utils.isEmpty(list)){
            return;
        }


        processList(true,company, list, null);
    }

    public static void processList(Company company, List list, Map<String, Object> map) {
        if (Utils.isEmpty(list)){
            return;
        }


        processList(true,company, list, map);
    }

    public static void processList(boolean initId,Company company,  List list) {
        if (Utils.isEmpty(list)){
            return;
        }

        processList(initId,company, list, null);
    }


    /**
     * 初始化数据
     * @param data
     * @param map - 属性名和属性值
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static synchronized void processEntity(boolean initId, Company company, Object data, Map<String, Object> map) {
        if (data == null){
            return;
        }

        if (initId) {
            ReflectionUtils.setFieldValue(data, "id", UuidUtils.getUUID());
        }

        ReflectionUtils.setFieldValue(data, "time", new Date());
        ReflectionUtils.setFieldValue(data, "companyId", company.getId());

        if (map != null) {
            for (String key : map.keySet()) {
                ReflectionUtils.setFieldValue(data, key, map.get(key));
            }
        }
    }

    /**
     * 初始化列表
     * @param list
     * @param map
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static synchronized void processList(boolean initId, Company company, List list, Map<String, Object> map) {
        if (Utils.isEmpty(list)){
            return;
        }

        Date date = new Date();
        for (int i=0;i<list.size(); i++) {
            if (initId) {
                ReflectionUtils.setFieldValue(list.get(i), "id", UuidUtils.getUUID());
            }

            ReflectionUtils.setFieldValue(list.get(i), "time", date);
            ReflectionUtils.setFieldValue(list.get(i), "companyId", company.getId());


            if (map != null) {
                for (String key : map.keySet()) {
                    ReflectionUtils.setFieldValue(list.get(i), key, map.get(key));
                }
            }
        }
    }
}
